package com.wwj.springboot.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author wwj
 */
@Slf4j
@Aspect
@Configuration
public class CacheRedisAspect {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 环绕增强：在增强中需要对被aop的方法放行 获取方法执行的返回值  然后return
     *
     */
    @Around("@annotation(com.wwj.springboot.annotation.AddCacheAnnotation)")
    public Object addCache(ProceedingJoinPoint joinPoint) throws Throwable {
        /**
         *  1.获取 key  和 hashKey(方法名+形参)
         */
        String key = joinPoint.getTarget().getClass().getName();
        log.info("获取到key：{}",key);
        StringBuffer stringBuffer = new StringBuffer();
//        拼接方法名
        stringBuffer.append(joinPoint.getSignature().getName());
//        拼接形参
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            stringBuffer.append(arg);
        }
        String hashKey = stringBuffer.toString();
        log.info("获取到 hashKey：{}",hashKey);

        /**
         * 2 查询redis
         */
        HashOperations opsForHash = redisTemplate.opsForHash();

        Object result = opsForHash.get(key, hashKey);

        if (result == null) {
            log.info("查询数据库数据");
            /**
             * 3 redis 查询结果为 null 查询数据库
             */
            result = joinPoint.proceed();
            Map map = new HashMap();
            map.put(hashKey,result);
//            创建缓存
            opsForHash.putAll(key,map);

//            设置失效过期时间
            redisTemplate.expire(key,1000, TimeUnit.SECONDS);

        }else {
            log.info("查询redis数据");
        }

        return result;

    }


    @Before("@annotation(com.wwj.springboot.annotation.DeleteCacheAnnotation)")
    public void deleteCache(JoinPoint joinPoint){
//        需要获取key
        String key = joinPoint.getTarget().getClass().getName();

        redisTemplate.delete(key);
    }
}
